package com.example.byd

import android.Manifest
import android.media.AudioManager
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import org.json.JSONObject
import org.webrtc.Camera1Enumerator
import org.webrtc.DefaultVideoDecoderFactory
import org.webrtc.DefaultVideoEncoderFactory
import org.webrtc.EglBase
import org.webrtc.IceCandidate
import org.webrtc.MediaConstraints
import org.webrtc.MediaStream
import org.webrtc.PeerConnection
import org.webrtc.PeerConnection.IceServer
import org.webrtc.PeerConnectionFactory
import org.webrtc.SessionDescription
import org.webrtc.SurfaceTextureHelper
import org.webrtc.SurfaceViewRenderer
import org.webrtc.VideoCapturer
import org.webrtc.audio.JavaAudioDeviceModule


class rtc : AppCompatActivity() ,SignalingClient.Callback{

    var peerConnectionFactory: PeerConnectionFactory? = null
    var peerConnection: PeerConnection? = null
    var localView: SurfaceViewRenderer? = null
    var remoteView: SurfaceViewRenderer? = null
    var mediaStream: MediaStream? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_rtc)


        val permissions = arrayOf(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
        requestPermissions(permissions,1)


        val eglBaseContext = EglBase.create().eglBaseContext

        // create PeerConnectionFactory

        // create PeerConnectionFactory
        PeerConnectionFactory.initialize(
            PeerConnectionFactory.InitializationOptions
                .builder(this)
                .createInitializationOptions()
        )
        val options = PeerConnectionFactory.Options()
        val defaultVideoEncoderFactory = DefaultVideoEncoderFactory(eglBaseContext, true, true)
        val defaultVideoDecoderFactory = DefaultVideoDecoderFactory(eglBaseContext)
        peerConnectionFactory = PeerConnectionFactory.builder()
            .setOptions(options)
            .setVideoEncoderFactory(defaultVideoEncoderFactory)
            .setVideoDecoderFactory(defaultVideoDecoderFactory)
            .createPeerConnectionFactory()

        val surfaceTextureHelper = SurfaceTextureHelper.create("CaptureThread", eglBaseContext)
        // create VideoCapturer
        // create VideoCapturer
        val videoCapturer = createCameraCapturer(false)


        val videoSource = peerConnectionFactory?.createVideoSource(
                videoCapturer!!.isScreencast
        )



        videoCapturer?.initialize(
            surfaceTextureHelper,
            applicationContext,
            videoSource?.capturerObserver
        )
        videoCapturer?.startCapture(480, 640, 30)

        localView = findViewById(R.id.localView)
        localView?.setMirror(true)
        localView?.init(eglBaseContext, null)

        // create VideoTrack

        // create VideoTrack
        val videoTrack = peerConnectionFactory?.createVideoTrack("100", videoSource)
//        // display in localView
        //        // display in localView
        videoTrack?.addSink(localView)


        remoteView = findViewById(R.id.remoteView)
        remoteView?.setMirror(false)
        remoteView?.init(eglBaseContext, null)




        mediaStream = peerConnectionFactory?.createLocalMediaStream("mediaStream")

        val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
        audioManager.mode = AudioManager.MODE_IN_COMMUNICATION

// 请求音频焦点以确保我们的应用控制音频

// 请求音频焦点以确保我们的应用控制音频
        val result = audioManager.requestAudioFocus(
            null,
            AudioManager.STREAM_VOICE_CALL,
            AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
        )
        if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
            // 如果获得了音频焦点，则设置为使用扬声器播放
            audioManager.isSpeakerphoneOn = true
            Log.e("rtc", "获得了音频焦点，设置为使用扬声器播放")
        }else{
            Log.e("rtc", "没有获得")
        }


        val audioSource = peerConnectionFactory?.createAudioSource(MediaConstraints())
        val audioTrack = peerConnectionFactory?.createAudioTrack("101", audioSource)


        mediaStream?.addTrack(videoTrack)
        mediaStream?.addTrack(audioTrack)

        SignalingClient.get()!!.setCallback(this)
        call()





    }






    private fun call() {
        val iceServers: MutableList<IceServer> = ArrayList()
        Log.i("bydsong","开始打电话")
        iceServers.add(IceServer.builder("stun:122.114.71.215:3478").createIceServer())
        peerConnection = peerConnectionFactory!!.createPeerConnection(
            iceServers,
            object : PeerConnectionAdapter("localconnection") {
                override fun onIceCandidate(iceCandidate: IceCandidate) {
                    super.onIceCandidate(iceCandidate)
                    Log.i("bydsong","yangyang onIceCandidate")
                    SignalingClient.get()!!.sendIceCandidate(iceCandidate)
                }

                override fun onAddStream(mediaStream: MediaStream) {
                    super.onAddStream(mediaStream)
                    Log.i("bydsong","yangyangon AddStream")
                    val remoteVideoTrack = mediaStream.videoTracks[0]
                    runOnUiThread { remoteVideoTrack.addSink(remoteView) }
                }
            })
        peerConnection!!.addStream(mediaStream)
        Log.i("bydsong","开始打电话111")
    }


    private fun createCameraCapturer(isFront: Boolean): VideoCapturer? {
        val enumerator = Camera1Enumerator(false)
        val deviceNames = enumerator.deviceNames

        // First, try to find front facing camera
        for (deviceName in deviceNames) {
            if (if (isFront) enumerator.isFrontFacing(deviceName) else enumerator.isBackFacing(
                    deviceName
                )
            ) {
                val videoCapturer: VideoCapturer? = enumerator.createCapturer(deviceName, null)
                if (videoCapturer != null) {
                    return videoCapturer
                }
            }
        }
        return null
    }


    override fun onCreateRoom() {
        Log.i("bydsong","创建房间")
    }

    override fun onPeerJoined() {
        Log.i("bydsong","有人加入")
    }

    override fun onSelfJoined() {
        peerConnection!!.createOffer(object : SdpAdapter("local offer sdp") {
           override fun onCreateSuccess(sessionDescription: SessionDescription) {
                super.onCreateSuccess(sessionDescription)
                peerConnection!!.setLocalDescription(
                    SdpAdapter("local set local"),
                    sessionDescription
                )
                SignalingClient.get()!!.sendSessionDescription(sessionDescription)
            }
        }, MediaConstraints())
    }

    override fun onPeerLeave(msg: String?) {
        TODO("Not yet implemented")
    }

    override fun onOfferReceived(data: JSONObject?) {
        runOnUiThread {
            peerConnection!!.setRemoteDescription(
                SdpAdapter("localSetRemote"),
                SessionDescription(SessionDescription.Type.OFFER, data!!.optString("sdp"))
            )
            peerConnection!!.createAnswer(object : SdpAdapter("localAnswerSdp") {
                override fun onCreateSuccess(sdp: SessionDescription) {
                    super.onCreateSuccess(sdp)
                    peerConnection!!.setLocalDescription(SdpAdapter("localSetLocal"), sdp)
                    SignalingClient.get()!!.sendSessionDescription(sdp)
                }
            }, MediaConstraints())
        }
    }

    override fun onAnswerReceived(data: JSONObject?) {
        peerConnection!!.setRemoteDescription(
            SdpAdapter("localSetRemote"),
            SessionDescription(SessionDescription.Type.ANSWER, data!!.optString("sdp"))
        )
    }

    override fun onIceCandidateReceived(data: JSONObject?) {
        peerConnection!!.addIceCandidate(
            IceCandidate(
                data!!.optString("id"),
                data!!.optInt("label"),
                data!!.optString("candidate")
            )
        )
    }


}